#include "mylog.h"
#include <string>
#include <thread>
#include <vector>
#include <chrono>
#include <cstdio>

namespace MyLog
{
    void bench(const std::string& name, size_t threadSize/*线程数*/, size_t msgCount/*总日志条数*/, size_t msgLen/*一条日志消息长度*/)
    {
        //获取指定日志器
        Logger::ptr logger = GetLogger(name);
        if(logger.get() == nullptr)
        {
            std::cout << "未找到指定日志器，退出" << std::endl;
            return;
        }

        std::cout << "输入线程数量 " << threadSize << std::endl;
        std::cout << "输出日志数量 " << msgCount << std::endl;
        std::cout << "输出日志大小 " << msgCount * msgLen / 1024 << " KB" << std::endl;
        //构造指定长度的信息
        std::string message(msgLen - 1, 'a');

        std::vector<std::thread> threads;
        std::vector<double> time_record(threadSize);  //记录花费时间
        size_t aveMsgCount = msgCount / threadSize;   //计算每个线程所需写入日志条数

        for(int i = 0; i < threadSize; ++i)
        {
            threads.emplace_back([&, i](){
                auto start = std::chrono::steady_clock::now();

                for(int j = 0; j < aveMsgCount; ++j)
                {
                    logger->FATAL(message.c_str());
                    // printf("lalala\n");
                }
                
                auto end = std::chrono::steady_clock::now();
                auto duration = end - start;
                auto convertDuration = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() ;
                // 转换为毫秒输出
                std::cout << "线程[" << i << "]耗时: " << (float)convertDuration / 1000 << " s" << std::endl;
                time_record[i] = (float)convertDuration / 1000;
            });
        }
        for(int i = 0; i < threadSize; ++i)
        {
            threads[i].join();
        }
        double max_time = 0;
        for(auto time : time_record)
        {
            max_time = std::max(max_time, time);
        }
        size_t aveCount = msgCount / max_time;
        size_t aveSize = (msgCount * msgLen) / max_time / 1024;
        std::cout << "总耗时 " << max_time << " s" << std::endl;
        std::cout << "平均每秒输出 " << aveCount << " 条日志" << std::endl;
        std::cout << "平均每秒输出 " << aveSize / 1024 << "MB 数据" << std::endl;
    }

    void SyncBench(size_t threadSize, size_t msgCount, size_t msgLen)
    {
        std::unique_ptr<GobalLoggerBuilder> builder(new GobalLoggerBuilder());
        if(builder.get() == nullptr)
        {
            std::cout << "指针为空" <<std::endl;
            return;
        }
        const std::string name = "同步日志测试器";
        builder->buildLoggerName(name);
        builder->buildLogSink<FileSink>("./log1.txt");
        builder->buildFormatter("%n");
        // builder->buildLogSink<StdioSink>();
        Logger::ptr logger = builder->build();
        // logger->FATAL("aaaa");
        info("********************************************************************");
        info("同步日志器测试：%d threads, %d msgCount, %d msgLen", threadSize, msgCount, msgLen);
        bench(name, threadSize, msgCount, msgLen);
    }

    void AsyncBench(size_t threadSize, size_t msgCount, size_t msgLen)
    {
        std::unique_ptr<GobalLoggerBuilder> builder(new GobalLoggerBuilder());
        if(builder.get() == nullptr)
        {
            std::cout << "指针为空" <<std::endl;
            return;
        }
        const std::string name = "异步日志测试器";
        builder->buildLoggerName(name);
        builder->buildLogSink<FileSink>("./log2.txt");
        builder->buildFormatter("%n");
        builder->buildLoggerType(MyLog::LoggerType::LOGGER_ASYNC);
        builder->buildTypeUnSafe();
        Logger::ptr logger = builder->build();
        info("********************************************************************");
        info("异步日志器测试：%d threads, %d msgCount, %d msgLen", threadSize, msgCount, msgLen);
        bench(name, threadSize, msgCount, msgLen);
    }
}

int main()
{
    //同步写日志
    MyLog::SyncBench(1, 1000000, 100);
    MyLog::SyncBench(5, 1000000, 100);
    //异步写日志
    MyLog::AsyncBench(1, 1000000, 100);
    MyLog::AsyncBench(5, 1000000, 100);
    return 0;
}


//************************************************************************************************************* */
// void test_printf_speed1() {
//     const int n = 1000000;
//     auto start = std::chrono::steady_clock::now();
    
//     for (int i = 0; i < n; ++i) {
//         printf("lalala\n");
//     }
    
//     auto end = std::chrono::steady_clock::now();
//     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
//     std::cout << "直接printf " << n << " 次耗时: " << duration.count() << " ms" << std::endl;
//     std::cout << "平均每次: " << duration.count() * 1000.0 / n << " μs" << std::endl;
// }
// void test_printf_speed2() 
// {
//     const int n = 1000000;
//     auto start = std::chrono::steady_clock::now();

//     for(int j = 0; j < 1000000; ++j)
//     {
//         printf("lalala\n");
//     }
    
//     auto end = std::chrono::steady_clock::now();
//     auto duration = end - start;
//     auto convertDuration = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() ;
//     // 转换为毫秒输出
//     std::cout << "直接printf " << n << " 次耗时: " << convertDuration << " ms" << std::endl;
// }
// int main()
// {
// //    test_printf_speed1();
//    test_printf_speed2();
   
//     return 0;
// }


